A/D変換の動作確認(2)



<項目>ソフト的な荒技を紹介(PICをSLEEP!しながらA/D変換)
    眠らせてA/D変換をするって?


ここがポイント
A/D モジュールはスリープ中も動作できます。

SLEEP 命令を実行させることで、ディジタル変換ノイズを除去することができます。変換が終了すると、GO/DONE ビットがクリアされて、結果がADRES レジスタにロードされます。A/D モジュールがスリープ中に動作するには、A/D クロックソースをRC(ADCS1:ADCS0 = 11)に設定する必要があります。スリープ中に変換するには、GO/DONEビットをセットした後すぐにSLEEP 命令を実行します。

図1にA/D変換のフローチャートを示します。
プログラムの解説については、「プログラムの説明(2)」の項をご参照ください。

A/D変換プログラム(2)のフローチャート
図1.A/D変換プログラム(2)
フローチャート

(注)以下に示すプログラムには、ホームページ画面作成の都合上、空白として全角文字のスペースなどが挿入されています。したがって、下記プログラムリストをそのままコピーしてMPLABのソースファイルとされた場合には、エラーとなることがあります。

→ここをクリックして、下記のプログラムをダウンロードするようにしてください。
<ダウンロードする>  ファイル名:「adconv2.asm」 サイズ2.27kバイト

→ここをクリックして、下記のオブジェクトファイルをダウンロードするようにしてください。
<ダウンロードする>  ファイル名:「adconv2.hex」 サイズ1173バイト

プログラムリスト中、青字となっている行が、前ページのA/D変換プログラム(1)で変更された部分です。

;***********************************************************
; A/D変換動作チェックプログラム(2)
; スリープ機能使用(A/D 割り込み使用)
; A/D変換入力端子(CH0/RA0)
; A/D変換の結果はLED点灯により確認
; RB1(MSB),RB0,RD7,RD6,RD5,RD4,RD3,RD2,RD1,RD0(LSB)
; の10ビット
;***********************************************************
    LIST   P=PIC16F877
    INCLUDE  P16F877.INC
;(1)プロセッサの種別指定
;(2)インクルードファイルの指定
;***********************************************************
; 変数定義とレジスタ割付
;***********************************************************
COUNT  EQU  20H

    ORG  0
;(3)ループカウンタ

;(4)プログラムの開始番地の指定
;***********************************************************
; 入出力ピン初期化
;***********************************************************
    BSF    STATUS,RP0
    MOVLW   B'10001110'
    MOVWF   ADCON1
    
BSF    PIE1,ADIE
    CLRF   TRISB
    CLRF   TRISD
    BCF    STATUS,RP0

    
MOVLW   B'11000001'
    MOVWF   ADCON0
    
BSF    INTCON,PEIE
;(5)Bank 1 へ切替
;(6)RA0のみアナログ、結果右詰
;(7)ADCON1レジスタの設定
;(7')A/D 割り込みを発生可にする
;(8)PortB 出力モードに設定
;   PortD 出力モードに設定
;(9)Bank 0 へ戻す
;
;(10')Frc,CH0 設定, A/D on
;(11)ADCON0レジスタの設定
;(11')周辺割り込みを発生させる
;***********************************************************
; メインプログラム
;***********************************************************
ADSTART
    
BCF    PIR1,ADIF
    CALL   TIME

    BSF    ADCON0,GO
    
SLEEP

    MOVF   ADRESH,W
    MOVWF   PORTB
    BSF    STATUS,RP0
    MOVF   ADRESL,W
    BCF    STATUS,RP0
    MOVWF   PORTD
    GOTO   ADSTART
;
;(12')A/D 割り込みフラグビットをクリアする
;(12)23.2μs 一定時間待つ
;  (2TAD [2×1.6μs]+アクィジション時間[20μs])
;(13)A/D スタート
;(13')SLEEP 命令を実行
;
;(16)A/D データ上位(データは右詰)
;(17)PortBへ A/D 結果を出力
;(18)Bank 1 へ切替
;(19)A/D データ下位
;(20)Bank 0 へ戻す
;(21)PortDへ A/D 結果を出力
;(22)A/D 変換を繰り返す
;***********************************************************
;23μs遅延サブルーチン(20MHzクロック時)
;***********************************************************
TIME
    MOVLW   25H
    MOVWF   COUNT
    NOP
LOOP
    DECFSZ  COUNT,F
    GOTO   LOOP
    RETURN

    END
;
;(23)1サイクル 25H = 37
;(24)1サイクル
;(25)1サイクル 微調整ダミー
;
;(26)1×(37-1)+2 = 38サイクル
;(27)2×(37-1) = 72サイクル
;(28)2サイクル
;   合計 115サイクル×0.2μs = 23μs
;(29)プログラム・ソースの終わり

【プログラムの説明(2)】
このプログラムについて、解説を加えておきましょう。ただし、前ページで解説したプログラム(1)の説明と重複する部分は省略します。 ここではプログラムリスト中、青字となっている行を解説します。その他の行はプログラムの説明(1)をご覧ください。

(7’)A/D 割り込みを発生可にする
PIE1レジスタは周辺機能の割り込みのイネーブルビットが割り当てられています。
PIE1レジスタの6ビット目のADIEビットは、A/D変換器割り込みイネーブルビットとなっていて、
ADIE=1 :A/D変換割り込みを使用可能にする
ADIE=0 :A/D変換割り込みを発生不可にする

BSF    PIE1,ADIE
「PIE1」レジスタのADIEビットを「1」にし、A/D変換割り込みを使用可能にする

(10’)Frc,CH0 設定,A/D on

ここがポイントSLEEPモードでA/D変換を行うため、A/D クロックソースをRC(ADCS1:ADCS0=11)にセットする必要があります。

「A/D変換の制御法」の表4.A/D変換用クロックの選択を参照してください。内部RC発振回路を使用するFrc指定の場合は、システムクロックには影響されず、2〜6μsの周波数になります。また、「A/D変換の制御法」の表1.ADCON0レジスタの機能説明表を参照してください。アナログチャネル指定ビットですが、CHSx=「000」とすることで、CH0(RA0)の指定になります。

bit7: A/D変換クロック(Frc)指定より ADCS1=「1」
bit6: A/D変換クロック(Frc)指定より ADCS0=「1」
bit5: アナログチャネルCH0(RA0)指定より、CHS2=「0」
bit4: アナログチャネルCH0(RA0)指定より、CHS1=「0」
bit3: アナログチャネルCH0(RA0)指定より、CHS0=「0」
bit2: A/D 変換ステータスビット(初期設定時は「0」としておく)
bit1: 機能なし(とりあえず「0」とでもしておく)
bit0: A/D ON ビット(A/D機能を使うので「1」としておく)

ということで、B’11000001’ (C1H)をWregにロードする。


(11’)周辺割り込みを発生させる
INTCON レジスタは割り込みの各種イネーブルおよびフラグビットが割り当てられているレジスタです。周辺機能の割り込みを使用可能にするためには、INTCONレジスタのPEIE ビットをセットします。
INTCONレジスタの6ビット目のPEIEビットは、周辺割り込みイネーブルビットとなっていて、
PEIE=1:すべてのマスクされていない周辺機能の割り込みを使用可能にする
PEIE=0:すべての周辺機能の割り込みを使用不可にする

BSF    INTCON,PEIE
「INTCON」レジスタのPEIEビットを「1」にし、周辺機能の割り込みを使用可能にする


(12’)A/D 割り込みフラグビットをクリアする
PIR1レジスタは周辺機能の割り込みのフラグビットが割り当てられています。
PIR1レジスタの6ビット目のADIFビットは、AD コンバータ割り込みフラグビットとなっていて、
ADIF=1:A/D変換が完了した
ADIF=0:A/D変換が完了していない

BCF    PIR1,ADIF
A/D変換をこれから行うため、「PIR1」レジスタのADIFビットを「0」にする。


(13’)SLEEP 命令を実行
ADCON0レジスタのGOビットをセットし、A/D変換を開始した直後に、プロセッサをSLEEPモードにします。A/D モジュールはスリープ中も動作できます。

ここがポイントSLEEPにする利点は、ディジタル変換ノイズを除去することです。

A/D変換が終了すると、PIR1レジスタの6ビット目のADIFビットが「1」にセットされ、結果がADRES レジスタにロードされます。

表1にSLEEPさせたときのA/D変換の実測結果と理論値を示します。ターゲットボードの値(実測値)と理論値を比べてみると、2V〜3Vあたりで最大2LSBの誤差があることが分かります。電圧換算すると、
2/1023×4.97V=約9.7mV程度になりました。
前ページ表2に示した通常のA/D変換動作の結果と大差ないことが確認されました。この結果から考えると、通常動作のA/D変換においてもディジタル変換ノイズの影響は小さく、わざわざSLEEPさせてクロックを止めたりしなくても通常にA/D変換機能を使えばよいことが分かりました。ただし、GNDラインを貧弱な配線にしたりすると、場合によっては、ディジタル変換ノイズの影響を受けてしまうこともあり得ます。そのときは、SLEEPさせることでノイズの除去効果が期待できると思います。(しかし私の考えとしては、こんなソフト的な荒技を使うより、まず第一に配線パターンを改善した方がよろしいかと思いますが。。。(^^;)

表1.A/D変換結果
A/D変換
入力電圧
( )内は実測値
出力結果
ターゲットボード 理論値
2進 16進 10進 2進 16進 10進
5V
(4.97V)
B’1111111111’ H’3FF’ D’1023’ B’1111111111’ H’3FF’ D’1023’
4V
(4.00V)
B’1100111000’ H’338’ D’824’ B’1100110111’ H’337’ D’823’
3V
(3.001V)
B’1001101000’ H’268’ D’616’ B’1001101010’ H’26A’ D’618’
2V
(2.001V)
B’0110011010’ H’19A’ D’410’ B’0110011100’ H’19C’ D’412’
1V
(1.001V)
B’0011001101’ H’0CD’ D’205’ B’0011001110’ H’0CE’ D’206’
0V
(0.000V)
B’0000000000’ H’000’ D’000’ B’0000000000’ H’000’ D’000’


次へは、「多入力のA/D変換法」について解説します。


<前ページへ> <次ページへ>
<TOPページへ>



テレワークならECナビ Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!
無料ホームページ 無料のクレジットカード 海外格安航空券 海外旅行保険が無料! 海外ホテル